////////////////////////////////////////////////////////////////////////////////
// Filename: terrain.ps
////////////////////////////////////////////////////////////////////////////////


//////////////
// TEXTURES //
//////////////
Texture2D colorTexture : register(t0);
Texture2D normalTexture : register(t1);


//////////////
// SAMPLERS //
//////////////
SamplerState SampleType;


//////////////////////
// CONSTANT BUFFERS //
//////////////////////
cbuffer LightBuffer
{
	float4 diffuseColor;
	float3 lightDirection;
	float padding;
};


//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
   	float3 normal : NORMAL;
	float3 tangent : TANGENT;
	float3 binormal : BINORMAL;
    float4 depthPosition : TEXCOORD1;
};


////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 TerrainPixelShader(PixelInputType input) : SV_TARGET
{
	float depthValue;
	float4 textureColor;
    float4 bumpMap;
    float3 bumpNormal;
    float3 lightDir;
    float lightIntensity;
    float4 color;


	// Get the depth value of the pixel by dividing the Z pixel depth by the homogeneous W coordinate.
	depthValue = input.depthPosition.z / input.depthPosition.w;

    // Sample the texture pixel at this location.
    textureColor = colorTexture.Sample(SampleType, input.tex);
	
	if(depthValue < 0.9f)
	{    
		// Sample the pixel in the bump map.
		bumpMap = normalTexture.Sample(SampleType, input.tex);

		// Expand the range of the normal value from (0, +1) to (-1, +1).
	    bumpMap = (bumpMap * 2.0f) - 1.0f;

		// Calculate the normal from the data in the bump map.
		bumpNormal = input.normal + bumpMap.x * input.tangent + bumpMap.y * input.binormal;

	    // Normalize the resulting bump normal.
		bumpNormal = normalize(bumpNormal);
	}
	else
	{
		bumpNormal = input.normal;
	}	
	
    // Invert the light direction for calculations.
    lightDir = -lightDirection;

    // Calculate the amount of light on this pixel based on the bump map normal value.
    lightIntensity = saturate(dot(bumpNormal, lightDir));

    // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
    color = saturate(diffuseColor * lightIntensity);

    // Combine the final bump light color with the texture color.
    color = color * textureColor;

    return color;
}